#pragma once
#include<QReadWriteLock>
#include"MemRecordStore.h"
using namespace std;

class SwitchRecordStore {
private:
    //会有很多线程同时操作（提交事务）
    MemRecordStore* tmpStore;   //MemRecordStore的操作安全在MemRecordStore内部保证
    //只有一个异步增量写入线程操作
    MemRecordStore* spareStore;
    QReadWriteLock switchLock;  //用来保证两个指针指向正常

    void switchStore(){
        switchLock.lockForWrite();
        spareStore->monoRecLock();   //为防止在更换时 备用MemStoredStore没有磁盘写完成
        //更换服务事务提交的MemRecordStore
        MemRecordStore* ptr = tmpStore;
        tmpStore = spareStore;
        spareStore = ptr;
        tmpStore->releaseRecLock();     //指针换了 所以tmpStore释放锁
        switchLock.unlock();
    }

public:

    SwitchRecordStore(){
        tmpStore = new MemRecordStore();
        spareStore = new MemRecordStore();
    }

    //析构函数里面都是同步释放 仅在最头部控制异步
    ~SwitchRecordStore(){
        MemUtil::clearPtrMem(tmpStore);
        MemUtil::clearPtrMem(spareStore);
    }

    int32_t addComitInfo(const vector<pair<ResourceInfo, vector<Record*>>>& upDateInfo, const vector<pair<ResourceInfo, vector<IndexRecord*>>>& indexUpDateInfo, const vector<pair<ResourceInfo, vector<uint64_t>>>& bitMapUpDateInfo){
        switchLock.lockForRead();               //防止操作时换指针
        const int32_t& recCount = tmpStore->addComitInfo(upDateInfo, indexUpDateInfo, bitMapUpDateInfo);
        switchLock.unlock();
        return recCount;
    }

    int32_t increWriteToDisk(){
        switchStore();
        return spareStore->increWriteToDisk();      //同一时间只有一个线程进此函数（换指针） 所以不用上锁
    }

    bool isResUnIncreWriteToDisk(const ResourceInfo& resInfo){
        switchLock.lockForRead();           //防止操作时换指针
        const bool& tmpStoreRes = tmpStore->isResUnIncreWriteToDisk(resInfo);
        const bool& spareStoreRes = spareStore->isResUnIncreWriteToDisk(resInfo);
        switchLock.unlock();
        return tmpStoreRes || spareStoreRes;
    }
};
